{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pose IO\n",
    "Rosetta兼容最常规的几种两种记录结构格式：PDB和Silent文件：\n",
    "- PDB文件可以从https://www.rcsb.org/ 数据库中获取；\n",
    "- Silent文件为Rosetta开发的pose压缩文件（其功能也是储存结构等信息，但其体积比PDB小了10倍之多，非常适合在超算中心进行的数据文件的传输）\n",
    "\n",
    "Rosetta为PDB的结构信息读入提供了非常丰富的接口，此处我们介绍主要4种结构信息读入相关的函数:\n",
    "- pose_from_pdb：从pdb文件读入并生成pose\n",
    "- pose_from_sequence：从一级序列信息生成pose\n",
    "- poses_from_silent：从silent文件读入并生成pose\n",
    "- pose_from_rcsb：从rcsb数据库远程获取PDB code数据并读入和生成pose\n",
    "\n",
    "一般而言，Rosetta输入的结构信息大多来源于PDB结构文件，经过处理后生成对应的Pose。以下将逐一介绍如何使用这些外部文件来生成Pose对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyRosetta-4 2020 [Rosetta PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release 2020.23+release.0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 2020-06-04T19:12:24] retrieved from: http://www.pyrosetta.org\n",
      "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n",
      "\u001b[0mcore.init: {0} \u001b[0mChecking for fconfig files in pwd and ./rosetta/flags\n",
      "\u001b[0mcore.init: {0} \u001b[0mRosetta version: PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release r257 2020.23+release.0d6f90a8cb9 0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 http://www.pyrosetta.org 2020-06-04T19:12:24\n",
      "\u001b[0mcore.init: {0} \u001b[0mcommand: PyRosetta -ex1 -ex2aro -database /opt/miniconda3/envs/pyrosetta/lib/python3.6/site-packages/pyrosetta/database\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0m'RNG device' seed mode, using '/dev/urandom', seed=1756574544 seed_offset=0 real_seed=1756574544 thread_index=0\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0mRandomGenerator:init: Normal mode, seed=1756574544 RG_type=mt19937\n"
     ]
    }
   ],
   "source": [
    "# 初始化（必须执行的步骤）:\n",
    "from pyrosetta import init\n",
    "init()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.从PDB文件生成Pose\n",
    "此处以人工设计的小蛋白PDB文件为例读入并生成Pose:\n",
    "![title](./img/demo-pdb.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.import_pose.import_pose: {0} \u001b[0mFile './data/pose_demo.pdb' automatically determined to be of type PDB\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 2 11\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 5 25\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYD\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAutomatically setting covalent bonds between metal ions and metal-binding residues.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAutomatically setting up constraints between metal ions and metal-binding residues.\n"
     ]
    }
   ],
   "source": [
    "from pyrosetta import pose_from_pdb\n",
    "pdb_pose = pose_from_pdb('./data/pose_demo.pdb')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "表明，PDB文件自动读入成功，并发现2对二硫键，位于2、11、5、25位。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PDB file name: ./data/pose_demo.pdb\n",
      "Total residues: 26\n",
      "Sequence: HCFHCRNIRFCSEDEEELRRAREECK\n",
      "Fold tree:\n",
      "FOLD_TREE  EDGE 1 26 -1 \n"
     ]
    }
   ],
   "source": [
    "# 打印Pose的基本信息\n",
    "print(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过python的print函数，我们可以直接打印pose对象中的一些基本信息，比如这个pose的pdb文件来源是pose_demo.pdb;\n",
    "其总氨基酸数目是26、氨基酸的序列是HCFHCRNIRFCSEDEEELRRAREECK。并且可以查看这个pose的foldtree连接上下游关系(可先忽略这个概念。)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.从序列文件生成Pose\n",
    "除了直接从PDB文件中读取所有的原子信息，pyrosetta中也支持直接通过命令行从一级结构信息直接构建线性结构。\n",
    "以下以构建5个连续的丙氨酸结构为例:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 从一级序列生成线性结构\n",
    "from pyrosetta import pose_from_sequence\n",
    "seq_pose = pose_from_sequence('AAAAA')\n",
    "seq_pose.dump_pdb('5A.pdb')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将pose输出成PDB结构之后，在pymol中打开可查看到:\n",
    "![title](./img/5A.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.从PDB代号生成Pose\n",
    "pyrosetta中也有内置相关的函数，可以直接从PDB数据中下载某个PDB编号，并进行对应的清洗，得到Pose的方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.import_pose.import_pose: {0} \u001b[0mFile '4R80.clean.pdb' automatically determined to be of type PDB\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m missing heavyatom:  OXT on residue SER:CtermProteinFull 76\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m missing heavyatom:  OXT on residue SER:CtermProteinFull 152\n"
     ]
    }
   ],
   "source": [
    "# 我们还可以从rscb的PDB数据库中直接下载并读入生成Pose\n",
    "from pyrosetta.toolbox.rcsb import pose_from_rcsb\n",
    "rcsb_pose = pose_from_rcsb('4R80')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "执行完代码后，你会发现当前文件夹中出现了4R80.clean.pdb和4R80.pdb两个PDB结构。使用pymol打开查看。\n",
    "会**发现执行clean之后的文件中，底物和水分子均被删除，侧链缺失的原子也被Rosetta自动补全。**\n",
    "![title](./img/pose_from_rcsb.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4 从Silent文件读取生成Pose\n",
    "RosettaSilent文件文件是一种Pose的压缩格式文件，可以用它存储大量的Pose信息，它的体积只有PDB文件的1/10。因此非常适合用于云端超算结果的储存和返回。但是Silent文件并不是人类可读的文件格式。需要使用额外的Rosetta app或从pyrosetta中进行读取。\n",
    "\n",
    "silent文件的example:\n",
    "\n",
    "SEQUENCE: AAAAA\n",
    "SCORE:     score description\n",
    "REMARK BINARY SILENTFILE\n",
    "SCORE:     0.000       AAAAA\n",
    "ANNOTATED_SEQUENCE: A[ALA:NtermProteinFull]AAAA[ALA:CtermProteinFull] AAAAA\n",
    "LAAAAAAAAAAAAAAAAH/pu/AAAAAAAAAAA5DJAA9By1+DAAAAAz9Bo/kW+YAEAAAAAUBn//Q90F9767l5v8iuq+SPUx9r9XUQp8iuq+SPUx7Ta8D1P8iuq+SPUx7Ta8D1vKkf5/QGs677OEn2PNlPRAZShD9Lpxe5vEGQ0/0ntm/rH6O5vG8Q0/QHLd6Lj/dAw AAAAA\n",
    "LPdUVAxrmE/jWThSJYSzfABiq1AULO60Ig9BsAhhUsAEkVXeJOUPwAV2LK/jEKQpJeHkYARaLqB067l5PhCZeA92Oz8zSuWgJHMPbAJ5GXB0OEn2vs6QgAxiHUCEpxe5P31SHAdnfzBkH6O5PbGrcA12gIBEj/dAQ AAAAA\n",
    "LrbnxA14q0B0s39TJd7R9A14q0BUOqkjJ0+1AB58xnCkufCKJI7n7Atn0GDE0HBYpAmwABhpNDB067l5v2irtAh8jWCEHYfSJuU//ABYVVB0OEn2PJnHFBNkyDBEpxe5vMdr+A9EUBAkH6O5vtqr+A5fBhBEj/dAw AAAAA\n",
    "LJ1IGBZHfrCk1ckiJbiwIBZtKVDEjCF+oms0OBJtfQDkXeboJ9X7QBBa4sCkM0TxJtv8GBlJbvD067l5Pe+ZIBRTvQC02lztJ3gnHB944lD0OEn2vML8IBlfOHEEpxe5PTboCBJQF0DkH6O5Pcf+HB13leDEj/dAQ AAAAA\n",
    "LrbnRB14q0D0s39bJkrcXB14q0DUOqkrJpspZBpsDREkufCSJAL2ZB9VDbEEKAM4PIUMbBVs9YEEKAM4v2TkZBJR8bD067l5vRfpPBdscIEE8CabpMYzYBdIAlD0OEn2P+U7dBhuOcDEpxe5vccJYB5e/6CkH6O5vMjJYBZM2qDEj/dAw AAAAA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.io.silent.SilentFileData: {0} \u001b[0mReading all structures from ./data/demo.silent\n",
      "\u001b[0mcore.io.silent.SilentFileData: {0} \u001b[0mFinished reading 2 structures from ./data/demo.silent\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 2 11\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 5 25\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 2 11\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 2 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 11 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 5 25\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 5 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 25 CYD\n",
      "PDB file name: /Users/kunkun/Desktop/PyRosetta培训资料/data/pose_demo.pdb\n",
      "Total residues: 26\n",
      "Sequence: HCFHCRNIRFCSEDEEELRRAREECK\n",
      "Fold tree:\n",
      "FOLD_TREE  EDGE 1 26 -1 \n",
      "PDB file name: /Users/kunkun/Desktop/PyRosetta培训资料/data/pose_demo1.pdb\n",
      "Total residues: 26\n",
      "Sequence: HCFHCRNIRFCSEDEEELRRAREECK\n",
      "Fold tree:\n",
      "FOLD_TREE  EDGE 1 26 -1 \n"
     ]
    }
   ],
   "source": [
    "# 读入Silent文件\n",
    "from pyrosetta.io import poses_from_silent\n",
    "\n",
    "poses = poses_from_silent('./data/demo.silent')\n",
    "poses = list(poses)\n",
    "for pose in poses:\n",
    "    print(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果表明，我准备的silent文件里面有2个Pose。通过python的list和for循环语句，我们可以轻松地访问每一个Pose的信息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PDB file name: /Users/kunkun/Desktop/PyRosetta培训资料/data/pose_demo1.pdb\n",
      "Total residues: 26\n",
      "Sequence: HCFHCRNIRFCSEDEEELRRAREECK\n",
      "Fold tree:\n",
      "FOLD_TREE  EDGE 1 26 -1 \n"
     ]
    }
   ],
   "source": [
    "first_pose = poses[1]\n",
    "print(first_pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.从Pose生成输出Silent/PDB文件\n",
    "从上面的4个例子中，我们已经学会了如何从Seq,PDB以及Silent文件中读入并生成Rosetta的Pose。那么接下来的最后一个例子就讲述一下如何从Pose输出对应的信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**从已经生成的pose输出PDB结构或Silent文件，仅需要调用Pose类中dump_pdb的方法函数即可或poses_to_silent函数即可。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 从Pose输出pdb\n",
    "pdb_pose.dump_pdb('./data/output.pdb')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 输出5个重复的pose到silent文件中\n",
    "from pyrosetta.io import poses_to_silent\n",
    "for i in range(5):\n",
    "    poses_to_silent(pdb_pose, './data/multi_AAAAA.silent')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 进阶Pose IO的小技巧:\n",
    "#### 1. 使用toolbox中的cleanATOM对PDB进行数据清洗，仅把ATOM和TER行进行分离:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyrosetta.toolbox import cleanATOM\n",
    "cleanATOM(\"./data/4R80.pdb\", out_file=\"./data/4R80_clean2.pdb\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2. 读入带有非标准氨基酸或氨基酸修饰的PDB结构; 如以4jfx这个PDBid的结构中，存在名为PTR(磷酸化酪氨酸)的残基。\n",
    "Rosetta中自带修饰的氨基酸有3种: PTR,SEP,TPO."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyRosetta-4 2020 [Rosetta PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release 2020.23+release.0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 2020-06-04T19:12:24] retrieved from: http://www.pyrosetta.org\n",
      "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n",
      "\u001b[0mcore.init: {0} \u001b[0mChecking for fconfig files in pwd and ./rosetta/flags\n",
      "\u001b[0mcore.init: {0} \u001b[0mRosetta version: PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release r257 2020.23+release.0d6f90a8cb9 0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 http://www.pyrosetta.org 2020-06-04T19:12:24\n",
      "\u001b[0mcore.init: {0} \u001b[0mcommand: PyRosetta -extra_res_fa ptm-caa/PTR.params -database /opt/miniconda3/envs/pyrosetta/lib/python3.6/site-packages/pyrosetta/database\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0m'RNG device' seed mode, using '/dev/urandom', seed=-204704293 seed_offset=0 real_seed=-204704293 thread_index=0\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0mRandomGenerator:init: Normal mode, seed=-204704293 RG_type=mt19937\n",
      "\u001b[0mcore.import_pose.import_pose: {0} \u001b[0mFile './data/4jfx_peptide.pdb' automatically determined to be of type PDB\n",
      "GNYVVTYA\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 需要额外读入ptm-caa的参数文件:\n",
    "init(\"-extra_res_fa ptm-caa/PTR.params\")\n",
    "ptms_pose = pose_from_pdb('./data/4jfx_peptide.pdb')\n",
    "print(ptms_pose.sequence())\n",
    "ptms_pose.dump_pdb('ptm.pdb')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![title](./img/ptms_peptide.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3. 读入带有金属离子的PDB文件\n",
    "参考: https://www.rosettacommons.org/docs/latest/rosetta_basics/non_protein_residues/Metals\n",
    "目前Rosetta能够自动处理的一些常见金属离子: Zn, Cu, Fe, Mg, Na, K, Ca等。但注意的是，rosetta并没有认识金属和氨基酸残基形成化学键。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyRosetta-4 2020 [Rosetta PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release 2020.23+release.0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 2020-06-04T19:12:24] retrieved from: http://www.pyrosetta.org\n",
      "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n",
      "\u001b[0mcore.init: {0} \u001b[0mChecking for fconfig files in pwd and ./rosetta/flags\n",
      "\u001b[0mcore.init: {0} \u001b[0mRosetta version: PyRosetta4.conda.mac.cxx11thread.serialization.python36.Release r257 2020.23+release.0d6f90a8cb9 0d6f90a8cb9fa0567ca76bb71ee93bfe73340c70 http://www.pyrosetta.org 2020-06-04T19:12:24\n",
      "\u001b[0mcore.init: {0} \u001b[0mcommand: PyRosetta -in:auto_setup_metals -database /opt/miniconda3/envs/pyrosetta/lib/python3.6/site-packages/pyrosetta/database\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0m'RNG device' seed mode, using '/dev/urandom', seed=-1567130914 seed_offset=0 real_seed=-1567130914 thread_index=0\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0mRandomGenerator:init: Normal mode, seed=-1567130914 RG_type=mt19937\n",
      "\u001b[0mcore.import_pose.import_pose: {0} \u001b[0mFile './data/3cjk.pdb' automatically determined to be of type PDB\n",
      "\u001b[0mcore.io.pose_from_sfr.PoseFromSFRBuilder: {0} \u001b[0mCD 171 was added by a jump, with base residue 81\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m missing heavyatom:  OXT on residue ILE:CtermProteinFull 68\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m missing heavyatom:  OXT on residue ARG:CtermProteinFull 143\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAutomatically setting covalent bonds between metal ions and metal-binding residues.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAdding covalent linkage between residue 11's  SG  atom and residue 144's CD   atom.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAdding covalent linkage between residue 80's  OG1 atom and residue 144's CD   atom.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAdding covalent linkage between residue 81's  SG  atom and residue 144's CD   atom.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAdding covalent linkage between residue 84's  SG  atom and residue 144's CD   atom.\n",
      "\u001b[0mcore.util.metalloproteins_util: {0} \u001b[0mAutomatically setting up constraints between metal ions and metal-binding residues.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在初始化的时候，需要设置metals的检测。\n",
    "init(\"-in:auto_setup_metals\")\n",
    "metal_protein_pose = pose_from_pdb('./data/3cjk.pdb')\n",
    "metal_protein_pose.dump_pdb('./data/3cjk_metalsetip.pdb')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![title](./img/metal_pose.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pyrosetta",
   "language": "python",
   "name": "pyrosetta"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
